package com.actions.bluetoothbox2.fragment;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actions.bluetoothbox2.R;
import com.actions.bluetoothbox2.app.BrowserActivity;
import com.actions.bluetoothbox2.util.Constant.IPCKey;
import com.actions.bluetoothbox2.util.Utils;
import com.actions.bluetoothbox2.widget.Wakeuplighttime;
import com.actions.ibluz.manager.BluzManager;
import com.actions.ibluz.manager.BluzManagerData;
import com.actions.ibluz.manager.BluzManagerData.AlarmEntry;
import com.actions.ibluz.manager.BluzManagerData.OnAlarmUIChangedListener;
import com.actions.ibluz.manager.BluzManagerData.OnManagerReadyListener;
import com.actions.ibluz.manager.BluzManagerData.OnSnoozeMessageReadyListener;
import com.actions.ibluz.manager.IAlarmManager;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;


public class AlarmClockFragment extends SherlockFragment {
    private static final String TAG = "AlarmClockFragment";

    private BrowserActivity mActivity;
    private View mView;
    private ListView mAlarmClockListView;
    private IAlarmManager mAlarmManager;
    private BluzManager mBluzManager;
    private AlarmClockAdapter mAlarmClockAdapter;
    private ArrayList<AlarmClockNode> mAlarmEntriesList;
    private ActionMode mActionMode = null;
    private Menu mMenu = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.v(TAG, "onCreate");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.v(TAG, "onCreateView");
        setHasOptionsMenu(true);
        mView = inflater.inflate(R.layout.fragment_alarmclock, container, false);
        mActivity = (BrowserActivity) getActivity();
        mBluzManager = mActivity.getBluzManager();
        mAlarmEntriesList = new ArrayList<AlarmClockNode>();
        mActivity.getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
        mActivity.tv_title.setText(getResources().getText(R.string.alarmclock));
        mActivity.title_img_right.setVisibility(View.VISIBLE);
        mActivity.mGlobalInfoLayout.setVisibility(View.GONE);
        mActivity.title_back.setVisibility(View.VISIBLE);
        if (mBluzManager != null) {
            mAlarmManager = mBluzManager.getAlarmManager(new OnManagerReadyListener() {
                @Override
                public void onReady() {
                    getSecond();
                }

            });

            mAlarmManager.setOnAlarmUIChangedListener(new OnAlarmUIChangedListener() {

                @Override
                public void onStateChanged(int state) {
                    if (state == 1) {
                        mActivity.showAlarmDialog(createAlarmDialog());
                    } else {
                        mActivity.dismissAlarmDialog();
                    }
                }

            });

            init();
        }
        return mView;
    }

    private AlertDialog createAlarmDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
        builder.setTitle(R.string.alarmclock);
        builder.setPositiveButton(R.string.alarmclock_snooze, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                mAlarmManager.snooze();
                dialog.dismiss();
                mAlarmManager.getSnoozeMessage(new OnSnoozeMessageReadyListener() {

                    @Override
                    public void onReady(int snooze_time, int snooze_count, int overtime) {
                        String snoozeMessage = mActivity.getString(R.string.alarmclock_snoozemessage_pre) + snooze_time
                                + mActivity.getString(R.string.alarmclock_snoozemessage_next);
                        Toast.makeText(mActivity, snoozeMessage, Toast.LENGTH_LONG).show();
                    }
                });

            }
        });
        builder.setNegativeButton(R.string.alarmclock_turnoff, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                mAlarmManager.off();
                dialog.dismiss();
            }
        });
        builder.setOnCancelListener(new OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                mAlarmManager.off();
            }
        });
        AlertDialog dg = builder.create();
        return dg;
    }

    @Override
    public void onPause() {
        Log.v(TAG, "onPause!");
        super.onPause();
        if (mActionMode != null) {
            mActionMode.finish();
        }
    }

    public void init() {
        final View addAlarmView = mView.findViewById(R.id.add_alarm);
        addAlarmView.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if (mAlarmEntriesList.size() < 4) {
                    changeToAlarmSetting(creatNewAlarmEntry(), null);
                } else {
                    Utils.displayToast(R.string.alarmclock_too_many_entries);
                }
            }
        });
        // refreshAlarmEntries();
        mAlarmClockListView = (ListView) mView.findViewById(R.id.alarms_list);
        mAlarmClockAdapter = new AlarmClockAdapter(mAlarmEntriesList, mActivity);

        mAlarmClockListView.setAdapter(mAlarmClockAdapter);
        mAlarmClockListView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                AlarmClockAdapter.ViewHolder holder = (AlarmClockAdapter.ViewHolder) view.getTag();
                holder.onOff.toggle();

                if (mActionMode != null) {
                    if (holder.onOff.isChecked()) {
                        mAlarmEntriesList.get(position).setFlag(true);
                    } else {
                        mAlarmEntriesList.get(position).setFlag(false);
                    }
                } else {
                    Wakeuplighttime mWakeuplighttime = new Wakeuplighttime();
                    mWakeuplighttime.wakeup_light_time = mAlarmEntriesList.get(position).wakeupLightTime;
                    mWakeuplighttime.id = mAlarmEntriesList.get(position).getAlarmEntry().index;
                    mWakeuplighttime.ringId = mAlarmEntriesList.get(position).getAlarmEntry().ringId;
                    changeToAlarmSetting(mAlarmEntriesList.get(position).getAlarmEntry(), mWakeuplighttime);
                }
            }

        });
        mAlarmClockListView.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

//                AlertDialog dialog = new AlertDialog.Builder(mActivity).setTitle(R.string.dialog_title_message)
//                        .setMessage(R.string.dialog_content_message)
//                        .setPositiveButton(R.string.action_submit, new DialogInterface.OnClickListener() {
//
//                            @Override
//                            public void onClick(DialogInterface dialog, int which) {
//                                List<AlarmEntry> tempList = new ArrayList<AlarmEntry>();
//                                ArrayList<AlarmClockNode> tempNode = new ArrayList<AlarmClockNode>();
//                                for (int i = 0; i < mAlarmEntriesList.size(); i++) {
//                                    if (mAlarmEntriesList.get(i).getFlag()) {
//                                        tempList.add(mAlarmEntriesList.get(i).getAlarmEntry());
//                                        tempNode.add(mAlarmEntriesList.get(i));
//                                    }
//                                }
//                                mAlarmEntriesList.removeAll(tempNode);
//                                for (int j = 0; j < tempList.size(); j++) {
//                                    mAlarmManager.remove(tempList.get(j));
//                                }
//                                notifyDataChanged();
//                                dialog.cancel();
//                            }
//                        }).setNegativeButton(R.string.action_cancel, new DialogInterface.OnClickListener() {
//                            @Override
//                            public void onClick(DialogInterface dialog, int which) {
//                                dialog.cancel();
//                            }
//                        }).create();
//                dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
//
//                    @Override
//                    public void onDismiss(DialogInterface dialog) {
//                    }
//                });
//                WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
//                params.width = Utils.screenSize(mActivity).x;
//                // params.height = 600 ;
//                dialog.getWindow().setAttributes(params);
//                dialog.show();
                if (mActionMode == null) {
                    mActionMode = getSherlockActivity().startActionMode(new ActionMode.Callback() {

                        @Override
                        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                            // TODO Auto-generated method stub
                            return false;
                        }

                        @Override
                        public void onDestroyActionMode(ActionMode mode) {
                            mActionMode = null;
                            notifyDataChanged();
                        }

                        @Override
                        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                            MenuInflater inflater = mode.getMenuInflater();
                            inflater.inflate(R.menu.listsetting4alarmclock_menu, menu);
                            notifyDataChanged();
                            return true;
                        }

                        @Override
                        public boolean onActionItemClicked(ActionMode mode, com.actionbarsherlock.view.MenuItem item) {
                            switch (item.getItemId()) {
                                case R.id.action_delete:
                                    List<AlarmEntry> tempList = new ArrayList<AlarmEntry>();
                                    ArrayList<AlarmClockNode> tempNode = new ArrayList<AlarmClockNode>();
                                    for (int i = 0; i < mAlarmEntriesList.size(); i++) {
                                        if (mAlarmEntriesList.get(i).getFlag()) {
                                            tempList.add(mAlarmEntriesList.get(i).getAlarmEntry());
                                            tempNode.add(mAlarmEntriesList.get(i));
                                        }
                                    }
                                    mAlarmEntriesList.removeAll(tempNode);
                                    for (int j = 0; j < tempList.size(); j++) {
                                        mAlarmManager.remove(tempList.get(j));
                                    }

                                    notifyDataChanged();
                                    mode.finish();
                                    return true;
                                default:
                                    return true;
                            }
                        }
                    });
                }
                return true;
            }
        });
    }

    private void getSecond() {
        int cmd_type = Integer.decode("0x51");
        int cmd_id = Integer.decode("0x98");
        mBluzManager.setOnCustomCommandListener(new BluzManagerData.OnCustomCommandListener() {
            @Override
            public void onReady(int i, int i1, int i2, byte[] bytes) {

                if (null != bytes && bytes.length != 0) {
                    mAlarmEntriesList.clear();
                    for (int j = 0; j < bytes.length / 44; j++) {
                        byte b[] = new byte[32];
                        for (int k = 44 * j; k < 32 + 44 * j; k++) {
                            b[k % 44] = bytes[k];
                        }
                        String name = new String(b);
                        int alarm_id = bytes[32 + 44 * j] & 0xFF;
                        int alarm_used = bytes[33 + 44 * j] & 0xFF;
                        int alarm_onoff = bytes[34 + 44 * j] & 0xFF;
                        int repeat = bytes[35 + 44 * j] & 0xFF;
                        int hour = bytes[36 + 44 * j] & 0xFF;
                        int minute = bytes[37 + 44 * j] & 0xFF;
                        int wakeupLightTime = bytes[38 + 44 * j] & 0xFF;
                        int ring_type = bytes[39 + 44 * j] & 0xFF;

                        byte seq[] = new byte[4];
                        for (int k = 44 * j + 40; k < 44 + 44 * j; k++) {
                            seq[k % 44 - 40] = bytes[k];
                        }
                        int ring_seq = Utils.LittleEndian.ByteArrayToInt(seq);
//Utils.LittleEndian.ByteArrayToInt(b)
                        Log.i("TAG", "name=" + name + "--id=" + alarm_id +
                                "--alarm_used=" + alarm_used + "--alarm_onoff=" + alarm_onoff
                                + "--repeat=" + repeat + "--time==" + hour + ":" + minute +
                                "--wakeupLightTime==" + wakeupLightTime + "--ring_type=" + ring_type
                                + "--ring_seq==" + ring_seq);
                        boolean[] repeat_b = new boolean[7];

                        if ((repeat & 0x01) == 0x01) {
                            repeat_b[0] = true;
                        } else {
                            repeat_b[0] = false;
                        }
                        if ((repeat & 0x02) == 0x02) {
                            repeat_b[1] = true;
                        } else {
                            repeat_b[1] = false;
                        }
                        if ((repeat & 0x04) == 0x04) {
                            repeat_b[2] = true;
                        } else {
                            repeat_b[2] = false;
                        }
                        if ((repeat & 0x08) == 0x08) {
                            repeat_b[3] = true;
                        } else {
                            repeat_b[3] = false;
                        }
                        if ((repeat & 0x10) == 0x10) {
                            repeat_b[4] = true;
                        } else {
                            repeat_b[4] = false;
                        }
                        if ((repeat & 0x20) == 0x20) {
                            repeat_b[5] = true;
                        } else {
                            repeat_b[5] = false;
                        }
                        if ((repeat & 0x40) == 0x40) {
                            repeat_b[6] = true;
                        } else {
                            repeat_b[6] = false;
                        }
                        AlarmEntry mAlarmEntry = new AlarmEntry();
                        mAlarmEntry.title = name;
                        mAlarmEntry.ringId = ring_seq;
                        mAlarmEntry.minute = minute;
                        mAlarmEntry.index = alarm_id;
                        mAlarmEntry.hour = hour;
                        mAlarmEntry.repeat = repeat_b;
                        mAlarmEntry.ringType = ring_type;
                        if (alarm_onoff == 1) {
                            mAlarmEntry.state = true;
                        } else mAlarmEntry.state = false;

                        AlarmClockNode alarmClockNode = new AlarmClockNode(mAlarmEntry, false, wakeupLightTime);
                        mAlarmEntriesList.add(alarmClockNode);
                    }
                    notifyDataChanged();
                }
            }
        });
        mBluzManager.sendCustomCommand(cmd_type << 8 | cmd_id, 0, 0, null);
    }

    private class AlarmClockAdapter extends BaseAdapter {
        public ArrayList<AlarmClockNode> list;

        public AlarmClockAdapter(ArrayList<AlarmClockNode> list, Context context) {
            this.list = list;
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }


        final class ViewHolder {
            TextView time;
            TextView description;
            TextView repeat;
            TextView wakeup_light_time;
            CheckBox onOff;

        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                convertView = LayoutInflater.from(mActivity).inflate(R.layout.alarmclock_item, null);
                holder = new ViewHolder();
                holder.time = (TextView) convertView.findViewById(R.id.alarmTimeText);
                holder.description = (TextView) convertView.findViewById(R.id.alarmDescriptionText);
                holder.repeat = (TextView) convertView.findViewById(R.id.alarmRepeatText);
                holder.wakeup_light_time = (TextView) convertView.findViewById(R.id.wakeup_light_time);
                holder.onOff = (CheckBox) convertView.findViewById(R.id.alarmSwitchBox);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            mActivity.mGlobalInfoLayout.setVisibility(View.GONE);
            AlarmClockNode clock = list.get(position);
            AlarmEntry entry = clock.alarmEntry;
            if (mActionMode != null) {
                holder.onOff.setButtonDrawable(R.drawable.checkbox_switch_style);
                holder.onOff.setChecked(list.get(position).flag);
            } else {
                holder.onOff.setButtonDrawable(R.drawable.alarm_on_off_style);
                holder.onOff.setChecked(list.get(position).getAlarmEntry().state);
            }

            holder.onOff.setTag(clock);
            holder.onOff.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    AlarmClockNode clock = (AlarmClockNode) v.getTag();
                    CheckBox checkbox = (CheckBox) v;
                    if (mActionMode != null) {
                        if (checkbox.isChecked()) {
                            clock.setFlag(true);
                        } else {
                            clock.setFlag(false);
                        }
                    } else {
                        AlarmEntry entry = clock.getAlarmEntry();
                        entry.state = checkbox.isChecked();
                        mActivity.sendAlarmClock(entry, 0, entry.repeat);
//                        mAlarmManager.set(entry);
                    }
                }
            });

            String sunday = getResources().getString(R.string.sun);
            String monday = getResources().getString(R.string.mon);
            String tuesday = getResources().getString(R.string.tue);
            String wednesday = getResources().getString(R.string.wed);
            String thursday = getResources().getString(R.string.thu);
            String friday = getResources().getString(R.string.fri);
            String saturday = getResources().getString(R.string.sat);

            String repeat = "";
            if (entry.repeat[0])
                repeat = (sunday + "  ");
            if (entry.repeat[1])
                repeat += (monday + "  ");
            if (entry.repeat[2])
                repeat += (tuesday + "  ");
            if (entry.repeat[3])
                repeat += (wednesday + "  ");
            if (entry.repeat[4])
                repeat += (thursday + "  ");
            if (entry.repeat[5])
                repeat += (friday + "  ");
            if (entry.repeat[6])
                repeat += saturday;
            if (!repeat.equalsIgnoreCase("")) {
                holder.repeat.setText(repeat);
                holder.repeat.setTextColor(getResources().getColor(R.color.darkorange));
            } else {
                String def = getResources().getString(R.string.alarmclock_repeat_default);
                holder.repeat.setText(def);
                holder.repeat.setTextColor(getResources().getColor(R.color.white));
            }
            int wakeUpLightTime = clock.wakeupLightTime;

            holder.wakeup_light_time.setText(getString(R.string.alarmclock_wakeup_light_time)
                    + "  " + wakeUpLightTime + getString(R.string.alarmclock_snoozemessage_next));
            int hour = entry.hour;
            int minute = entry.minute;
            if (minute + wakeUpLightTime >= 60) {
                minute = minute + wakeUpLightTime - 60;
                if (hour == 23) {
                    hour = 0;
                } else {
                    hour += 1;
                }
            } else {
                minute += wakeUpLightTime;
            }
            String format = String.format("%02d:%02d", hour, minute);
            holder.time.setText(format);

            if (entry.title != null && !entry.title.equalsIgnoreCase("")) {
                holder.description.setText(entry.title);
            } else {
                String def = getResources().getString(R.string.alarmclock_description_hint);
                holder.description.setText(def);
            }

            convertView.setTag(holder);
            return convertView;
        }
    }

    private void notifyDataChanged() {
        mAlarmClockAdapter.notifyDataSetChanged();
    }

    private AlarmEntry creatNewAlarmEntry() {
        boolean isHolded;
        int index = 1;
        for (int i = 1; i < 256; i++) {
            isHolded = false;

            for (int j = 0; j < mAlarmEntriesList.size(); j++) {
                if (mAlarmEntriesList.get(j).alarmEntry.index == i) {
                    isHolded = true;
                }
            }

//            for (AlarmEntry entry : mAlarmManager.getList()) {
//                if (entry.index == i) {
//                    isHolded = true;
//                    break;
//                }
//            }

            if (!isHolded) {
                index = i;
                break;
            }
        }
        AlarmEntry entry = new AlarmEntry();
        entry.index = index;
        entry.ringType = 0;
        Calendar calendar = Calendar.getInstance();
        entry.hour = calendar.get(Calendar.HOUR_OF_DAY);
        entry.minute = calendar.get(Calendar.MINUTE);
        return entry;
    }

    private void changeToAlarmSetting(AlarmEntry entry, Wakeuplighttime mWakeuplighttime) {
        AlarmClockSettingFragment fragment = new AlarmClockSettingFragment();
        Bundle bundle = new Bundle();
        bundle.putParcelable(IPCKey.ALARM_ENTRY, entry);
        bundle.putSerializable("Second", mWakeuplighttime);
        fragment.setArguments(bundle);
        mActivity.replaceFragment(fragment, SlideLeftFragment.FRAGMENT_TAG_ALARM_SETTING);
    }

    private class AlarmClockNode {
        public AlarmEntry alarmEntry;
        public Boolean flag;
        public int wakeupLightTime;

        AlarmClockNode(AlarmEntry alarmEntry, Boolean flag, int wakeupLightTime) {
            this.alarmEntry = alarmEntry;
            this.flag = flag;
            this.wakeupLightTime = wakeupLightTime;
        }

        public AlarmEntry getAlarmEntry() {
            return alarmEntry;
        }

        public Boolean getFlag() {
            return flag;
        }

        public void setFlag(Boolean flag) {
            this.flag = flag;
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        mMenu = menu;
        inflater.inflate(R.menu.alarmclock_menu, menu);
    }

    @Override
    public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) {
        mActivity.menuItemSelected(null, item.getItemId());
        return super.onOptionsItemSelected(item);
    }

}
